﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Madrigal
{
    class Option
    {
        #region Variable Declarations
        public string filename = "";
        public int nSoundEffect;
        public int nResWidth;
        public int nResHeight;
        public bool bStartFullScreen;
        public int nTextureQuality;
        public int nViewArea;
        public int nObjectDetail;
        public int nObjectDistant;
        public int nShadow;
        public int nToggleScreen;
        public bool bOperator;
        public Int32[] dwChatFilter = new int[5];
        public Int32 dwChatFileterEtc;
        public int nBloom;
        public int nMonName;
        public int nPlayerName;
        public int nOtherPlayerName;
        public int nToolTipTexture;
        public int nToolTipText;

        public int nSfxLevel;

        public bool bWeatherEffect;
        public bool bVoice;
        public float fEffectVolume;
        public float fBGMVolume;

        public int nWindowAlpha;
        public int nWindowEffect;

        public int nSlangWord;

        public int nChatCommand;

        public int nInstantHelp;

        public int nInterface;
        public bool bRollEffect;

        public bool bSay;
        public bool bTrade;
        public bool bParty;
        public bool bShout;
        public bool bMessengerJoin;
        public bool bMessenger;

        public bool bBattleBGM;

        public bool bGameGradeRendering;

        public int nSer;
        public int nMSer;

        public bool bSaveAccount;
        public string szAccount = "";
        public bool bNotice;
        public bool bTip;
        public TimeSpan tNoticeTime;

        public int nGuide1, nGuide2, nGuide3, nTutorialLv;

        public bool bViewMask, bIsShowReSkillMessage;
        public string ipAddress = "";

        public bool bExitChange, bSpecBump;

        public bool bDamageRender, bVisibleBuffTimeRender;

        public int mouseSpeed;
        public bool bSFXRenderOff, bCameraLock, bAutoAttack;
        public int guide;

        // Y Gamma Control
        public int nOverBright;
        public float fGamma;
        public float fContrast;

        public int bufferStatusMode;

        public bool bZoomLimit;

        #endregion

        #region Constants

        public const int ChatStyleGeneral = 0x0001;
        public const int ChatStyleWhisper = 0x0002;
        public const int ChatStyleShout = 0x0004;
        public const int ChatStyleParty = 0x0008;
        public const int ChatstyleGuild = 0x0010;

        public const int ChatStyleHelp = 0x0060;
        public const int ChatStyleHelpClient = 0x0020;
        public const int ChatStyleHelpChat = 0x0020;
        public const int ChatStyleSystem = 0x0180;
        public const int ChatStyleSystemClient = 0x0080;
        public const int ChatStyleSystemChat = 0x0100;
        public const int ChatStyleGame = 0x0600;
        public const int ChatStyleGameClient = 0x0200;
        public const int ChatStyleGameChat = 0x0400;

        public const bool Finished = true;

        public char[] separators = { ' ', '\t' };

        #endregion

        public Option()
        {
            filename = "";
            bWeatherEffect = true;
            bOperator = false;
            nResWidth = 1024;
            nResHeight = 768;
            bStartFullScreen = true;
            nTextureQuality = 1;
            nViewArea = 1;
            nObjectDistant = 1;
            nObjectDetail = 1;
            nShadow = 2;
            nWindowAlpha = 255;
            nWindowEffect = 0;
            nSlangWord = 0;
            nChatCommand = 0;
            nInstantHelp = 1;
            nInterface = 1;
            bRollEffect = false;

            bSaveAccount = false;
            szAccount = "";
            bNotice = true;
            bTip = true;
            tNoticeTime = TimeSpan.Zero;
            bTrade = true;
            bSay = true;
            bParty = true;
            bShout = true;
            bMessengerJoin = true;
            bMessenger = true;

            bBattleBGM = false;

            bGameGradeRendering = false;

            nToggleScreen = 0;
            nSer = nMSer = 0;
            nBloom = 0;

            nMonName = 1;
            nToolTipTexture = 0;
            nToolTipText = 0;

            bVoice = true;
            fEffectVolume = 1.0f;
            fBGMVolume = 0.5f;
            nGuide1 = nGuide2 = nGuide3 = 0;

            nTutorialLv = 0;

            bViewMask = true;

            bIsShowReSkillMessage = true;
            guide = 0;

            dwChatFilter[0] = ChatStyleGeneral | ChatStyleWhisper | ChatStyleShout | ChatStyleParty | ChatstyleGuild;
            dwChatFilter[1] = ChatStyleGeneral | ChatStyleWhisper;
            dwChatFilter[2] = ChatStyleGeneral | ChatStyleShout;
            dwChatFilter[3] = ChatStyleGeneral | ChatStyleParty;
            dwChatFilter[4] = ChatStyleGeneral | ChatstyleGuild;
            dwChatFileterEtc = ChatStyleHelpChat | ChatStyleSystemChat | ChatStyleGameClient;

            ipAddress = "";
            nSfxLevel = 5;
            bExitChange = false;
            bSpecBump = true;

            bDamageRender = false;
            bVisibleBuffTimeRender = true;
            mouseSpeed = 1;
            bSFXRenderOff = false;

            bCameraLock = true;
            bAutoAttack = true;
            nPlayerName = 1;
            nOtherPlayerName = 1;

            nOverBright = 10;
            fGamma = 1.0f;
            fContrast = 1.0f;

            bufferStatusMode = 0;

            bZoomLimit = true;
        }

        public int Load(string filename)
        {
            StreamReader sReader = new StreamReader(filename);
            try
            {
                while (!sReader.EndOfStream)
                {
                    string line = sReader.ReadLine();
                    if (line.Trim() == "" || line.StartsWith("//"))
                        continue;
                    string[] lineData = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    switch (lineData[0].ToLower())
                    {
                        #region Options
                        case "resolution":
                            {
                                nResWidth = int.Parse(lineData[1]);
                                nResHeight = int.Parse(lineData[2]);
                                // ver9 and above addition
                                if (nResWidth != 800 && nResWidth != 1024 && nResWidth != 1280)
                                    nResWidth = 800;
                                if (nResHeight != 600 && nResHeight != 768 && nResHeight != 1024)
                                    nResHeight = 600;
                            }
                            break;
                        case "fullscreen":
                            {
                                if (int.Parse(lineData[1]) == 0)
                                    bStartFullScreen = false;
                                else if (int.Parse(lineData[1]) == 1)
                                    bStartFullScreen = true;
                                else
                                    bStartFullScreen = true;
                            }
                            break;
                        case "texture": nTextureQuality = int.Parse(lineData[1]); break;
                        case "view": nViewArea = int.Parse(lineData[1]); break;
                        case "distant": nObjectDistant = int.Parse(lineData[1]); break;
                        case "shadow": nShadow = int.Parse(lineData[1]); break;
                        case "bloom": nBloom = int.Parse(lineData[1]); break;
                        case "detail": nObjectDetail = int.Parse(lineData[1]); break;
                        case "hotkey": break;
                        case "WindowAlpha": nWindowAlpha = int.Parse(lineData[1]); break;
                        case "SlangWord": nSlangWord = int.Parse(lineData[1]); break;
                        case "ChatCommand": nChatCommand = int.Parse(lineData[1]); break;
                        case "InstantHelp": nInstantHelp = int.Parse(lineData[1]); break;
                        case "Interface": nInterface = int.Parse(lineData[1]); break;
                        case "RollEffect": bRollEffect = bool.Parse(lineData[1]); break;
                        case "account":
                            string account = lineData[1].Replace("\"", String.Empty);
                            if (account.Length > 64)
                                account = account.Substring(0, 64);
                            szAccount = account;
                            break;
                        case "saveAccount": bSaveAccount = bool.Parse(lineData[1]); break;
                        case "notice": bNotice = bool.Parse(lineData[1]); break;
                        case "noticeTime": tNoticeTime = TimeSpan.Parse(lineData[1]); break;
                        case "tip": bTip = bool.Parse(lineData[1]); break;
                        case "Trade": bTrade = bool.Parse(lineData[1]); break;
                        case "Say": bSay = bool.Parse(lineData[1]); break;
                        case "Party": bParty = bool.Parse(lineData[1]); break;
                        case "sunkist":
                            {
                                bOperator = true;
                                nToggleScreen = int.Parse(lineData[1]);
                            }
                            break;
                        case "Shout": bShout = bool.Parse(lineData[1]); break;
                        case "MessengerJoin": bMessengerJoin = bool.Parse(lineData[1]); break;
                        case "Messenger": bMessenger = bool.Parse(lineData[1]); break;
                        case "BattleBGM": bBattleBGM = bool.Parse(lineData[1]); break;
                        case "GameGrade": bGameGradeRendering = bool.Parse(lineData[1]); break;
                        case "Server":
                            {
                                nSer = int.Parse(lineData[1]);
                                nMSer = int.Parse(lineData[2]);
                            }
                            break;
                        case "Sound":
                            {
                                bVoice = bool.Parse(lineData[1]);
                                fEffectVolume = float.Parse(lineData[2]);
                                fBGMVolume = float.Parse(lineData[3]);
                            }
                            break;
                        case "Guide": nGuide1 = int.Parse(lineData[1]); break;
                        case "Guide2": nGuide2 = int.Parse(lineData[1]); break;
                        case "Guide3": nGuide3 = int.Parse(lineData[1]); break;
                        case "SkillShowMessage": bIsShowReSkillMessage = bool.Parse(lineData[1]); break;
                        case "ChatFilter0":
                            {
                                dwChatFilter[0] = int.Parse(lineData[1]);
                                dwChatFilter[0] &= ~(ChatStyleHelp | ChatStyleSystem | ChatStyleGame);
                            }
                            break;
                        case "ChatFilter1":
                            {
                                dwChatFilter[1] = int.Parse(lineData[1]);
                                dwChatFilter[1] &= ~(ChatStyleHelp | ChatStyleSystem | ChatStyleGame);
                            }
                            break;
                        case "ChatFilter2":
                            {
                                dwChatFilter[2] = int.Parse(lineData[1]);
                                dwChatFilter[2] &= ~(ChatStyleHelp | ChatStyleSystem | ChatStyleGame);
                            }
                            break;
                        case "ChatFilter3":
                            {
                                dwChatFilter[3] = int.Parse(lineData[1]);
                                dwChatFilter[3] &= ~(ChatStyleHelp | ChatStyleSystem | ChatStyleGame);
                            }
                            break;
                        case "ChatFilter4":
                            {
                                dwChatFilter[4] = int.Parse(lineData[1]);
                                dwChatFilter[4] &= ~(ChatStyleHelp | ChatStyleSystem | ChatStyleGame);
                            }
                            break;
                        case "ChatFilterEtc": dwChatFileterEtc = ChatStyleHelpChat | ChatStyleSystemChat | ChatStyleGameClient; break;
                        case "ip": ipAddress = lineData[1].Replace("\"", String.Empty); break;
                        case "SpecBumpEffect": bSpecBump = bool.Parse(lineData[1]); break;
                        case "DamageRender": bDamageRender = bool.Parse(lineData[1]); break;
                        case "BuffTimeRender": bVisibleBuffTimeRender = bool.Parse(lineData[1]); break;
                        case "MouseSpeed": mouseSpeed = int.Parse(lineData[1]); break;
                        case "SFXRenderOff": bSFXRenderOff = bool.Parse(lineData[1]); break;
                        case "CameraLock": bCameraLock = bool.Parse(lineData[1]); break;
                        case "AutoAttack": bAutoAttack = bool.Parse(lineData[1]); break;
                        case "PRenderName": nPlayerName = int.Parse(lineData[1]); break;
                        case "OPRenderName": nOtherPlayerName = int.Parse(lineData[1]); break;
                        case "NRenderName": nMonName = int.Parse(lineData[1]); break;
                        case "BRIGHT": nOverBright = int.Parse(lineData[1]); break;
                        case "GAMMA": fGamma = float.Parse(lineData[1]); break;
                        case "CONTRAST": fContrast = float.Parse(lineData[1]); break;
                        case "BUFFSTATUSMODE": bufferStatusMode = int.Parse(lineData[1]); break;
                        case "ZOOMLIMIT": bZoomLimit = bool.Parse(lineData[1]); break;
                        case "SFXLEVEL": nSfxLevel = int.Parse(lineData[1]); break;
                        case "WEATHEREFFECT": bWeatherEffect = bool.Parse(lineData[1]); break;
                        case "VIEWMASK": bViewMask = bool.Parse(lineData[1]); break;
                        #endregion
                    }
                }
            }
            catch (Exception ex)
            {
                //To do : Write log with Exception message and source
            }
            finally { sReader.Close(); }
            return -1;
        }

        public int Save(string filename)
        {
            StreamWriter sWriter = new StreamWriter("neuz.ini");
            sWriter.WriteLine("// neuz browser ini file");
            sWriter.WriteLine("resolution {0} {1}", nResWidth, nResHeight);
            sWriter.WriteLine("fullscreen {0}", bStartFullScreen ? 1 : 0);
            sWriter.WriteLine("texture {0}", nTextureQuality);
            sWriter.WriteLine("view {0}", nViewArea);
            sWriter.WriteLine("detail {0}", nObjectDistant);
            sWriter.WriteLine("distant {0}", nObjectDistant);
            sWriter.WriteLine("shadow {0}", nShadow);
            sWriter.WriteLine("bloom {0}", nBloom);
            sWriter.WriteLine("WindowAlpha {0}", nWindowAlpha);
            sWriter.WriteLine("SlangWord {0}", nSlangWord);
            sWriter.WriteLine("ChatCommand {0}", nChatCommand);
            sWriter.WriteLine("InstantHelp {0}", nInstantHelp);
            sWriter.WriteLine("Interface {0}", nInterface);
            sWriter.WriteLine("RollEffect {0}", bRollEffect ? 1 : 0);
            sWriter.WriteLine("saveAccount {0}", bSaveAccount ? 1 : 0);
            sWriter.WriteLine("account \"{0}\"", szAccount);
            sWriter.WriteLine("notice {0}", bNotice ? 1 : 0);
            sWriter.WriteLine("noticeTime {0}", tNoticeTime);
            sWriter.WriteLine("tip {0}", bTip ? 1 : 0);
            sWriter.WriteLine("Trade {0}", bTrade ? 1 : 0);
            sWriter.WriteLine("Say {0}", bSay ? 1 : 0);
            sWriter.WriteLine("Party {0}", bParty ? 1 : 0);
            if (bOperator)
                sWriter.WriteLine("sunkist {0}", nToggleScreen);
            sWriter.WriteLine("Shout {0}", bShout ? 1 : 0);
            sWriter.WriteLine("MessengerJoin {0}", bMessengerJoin ? 1 : 0);
            sWriter.WriteLine("Messenger {0}", bMessenger ? 1 : 0);
            sWriter.WriteLine("BattleBGM {0}", bBattleBGM ? 1 : 0);
            sWriter.WriteLine("Server {0} {1}", nSer, nMSer);
            sWriter.WriteLine("Sound {0} {1} {2}", bVoice ? 1 : 0, fEffectVolume, fBGMVolume);
            sWriter.WriteLine("Guide {0}", nGuide1);
            sWriter.WriteLine("Guide2 {0}", nGuide2);
            sWriter.WriteLine("Guide3 {0}", nGuide3);
            sWriter.WriteLine("SkillShowMessage {0}", bIsShowReSkillMessage ? 1 : 0);
            sWriter.WriteLine("ChatFilter0 {0}", dwChatFilter[0]);
            sWriter.WriteLine("ChatFilter1 {0}", dwChatFilter[1]);
            sWriter.WriteLine("ChatFilter2 {0}", dwChatFilter[2]);
            sWriter.WriteLine("ChatFilter3 {0}", dwChatFilter[3]);
            sWriter.WriteLine("ChatFilter4 {0}", dwChatFilter[4]);
            sWriter.WriteLine("ChatFilterEtc {0}", dwChatFileterEtc);
            sWriter.WriteLine("ip \"{0}\"", ipAddress);
            sWriter.WriteLine("DamageRender {0}", bDamageRender ? 1 : 0);
            sWriter.WriteLine("BuffTimeRender {0}", bVisibleBuffTimeRender ? 1 : 0);
            sWriter.WriteLine("MouseSpeed {0}", mouseSpeed);
            sWriter.WriteLine("SFXRenderOff {0}", bSFXRenderOff ? 1 : 0);
            sWriter.WriteLine("CameraLock {0}", bCameraLock ? 1 : 0);
            sWriter.WriteLine("AutoAttack {0}", bAutoAttack ? 1 : 0);
            sWriter.WriteLine("PRenderName {0}", nPlayerName);
            sWriter.WriteLine("OPRenderName {0}", nOtherPlayerName);
            sWriter.WriteLine("NRenderName {0}", nMonName);
            sWriter.WriteLine("BRIGHT {0}", nOverBright);
            sWriter.WriteLine("GAMMA {0}", fGamma);
            sWriter.WriteLine("CONTRAST {0}", fContrast);
            sWriter.WriteLine("BUFFSTATUSMODE {0}", bufferStatusMode);
            sWriter.WriteLine("ZOOMLIMIT {0}", bZoomLimit ? 1 : 0);
            sWriter.WriteLine("SFXLEVEL {0}", nSfxLevel);
            sWriter.WriteLine("WEATHEREFFECT {0}", bWeatherEffect);
            sWriter.WriteLine("VIEWMASK {0}", bViewMask ? 1 : 0);
            sWriter.Flush();
            sWriter.Close();
            return -1;
        }

        public int LoadToolTip(string filename)
        {
            return -1;
        }

        // Checks the current dimensions to see if the graphicsDevice
        // supports it. If not it defaults to 800x600
        public void CheckResolution(GraphicsDeviceManager graphicsDeviceManager)
        {
            bool bResolution = false;

            foreach (DisplayMode dm in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
            {
                if ((dm.Width == nResWidth) && (dm.Height == nResHeight))
                {
                    // The mode is supported, so set the buffer formats, apply the changes
                    // and return
                    graphicsDeviceManager.PreferredBackBufferWidth = nResWidth;
                    graphicsDeviceManager.PreferredBackBufferHeight = nResHeight;

                    // Check if the full screen flag is true
                    // then change to full screen
                    if (bStartFullScreen)
                        graphicsDeviceManager.IsFullScreen = true;
                    else
                        graphicsDeviceManager.IsFullScreen = false;

                    // Apply the changes to the GraphicsDeviceManager
                    graphicsDeviceManager.ApplyChanges();
                }
                else
                {
                    //Default to 800x600
                    //Error("We Cannot support this resolution! - Width: {0}, Height: {1} ", nResWidth, nResHeight);
                    nResWidth = 800;
                    nResHeight = 600;
                    graphicsDeviceManager.PreferredBackBufferWidth = nResWidth;
                    graphicsDeviceManager.PreferredBackBufferHeight = nResHeight;
                    if (bStartFullScreen)
                        graphicsDeviceManager.IsFullScreen = true;
                    else
                        graphicsDeviceManager.IsFullScreen = false;
                    graphicsDeviceManager.ApplyChanges();
                }
            }
        }

    }
}